package com.pointcircle.estate.server.framework.web.api;

import java.util.LinkedList;
import java.util.List;

import javax.validation.constraints.Size;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.pointcircle.core.IRepository;
import com.pointcircle.core.entity.User;
import com.pointcircle.core.repository.UserRepository;
import com.pointcircle.core.web.EntityVo;
import com.pointcircle.core.web.FormVo;
import com.pointcircle.core.web.IAddRest;
import com.pointcircle.core.web.IEditRest;
import com.pointcircle.core.web.IFindAllRest;
import com.pointcircle.core.web.IFindByIdRest;
import com.pointcircle.core.web.RestResponseElement;
import com.pointcircle.core.web.annotation.CurrentUser;
import com.pointcircle.estate.server.framework.entity.BatchCc;
import com.pointcircle.estate.server.framework.entity.BatchPurpose;
import com.pointcircle.estate.server.framework.entity.BatchType;
import com.pointcircle.estate.server.framework.entity.BatchUser;
import com.pointcircle.estate.server.framework.entity.CheckQualityBatch;
import com.pointcircle.estate.server.framework.repository.BatchCcRepository;
import com.pointcircle.estate.server.framework.repository.BatchUserRepository;
import com.pointcircle.estate.server.framework.repository.BidSectionRepository;
import com.pointcircle.estate.server.framework.repository.CheckQualityBatchRepository;

import lombok.Getter;
import lombok.Setter;

@RestController
@RequestMapping("/api/checkQualityBatch")
public class CheckQualityBatchApi implements
	IFindAllRest<CheckQualityBatch, String, CheckQualityBatchApi.CheckQualityBatchEntityVo>,
    IFindByIdRest<CheckQualityBatch, String, CheckQualityBatchApi.CheckQualityBatchEntityVo>,
    IAddRest<CheckQualityBatch, String, CheckQualityBatchApi.CheckQualityBatchEntityVo, CheckQualityBatchApi.CheckQualityBatchFormVo>,
 	IEditRest<CheckQualityBatch, String, CheckQualityBatchApi.CheckQualityBatchEntityVo, CheckQualityBatchApi.CheckQualityBatchFormVo> {
	
	@Autowired
	private CheckQualityBatchRepository repository;
	
	@Autowired
	private BidSectionRepository bidSectionRepository;
	
	@Autowired
	private UserRepository userRepository;
	
	@Autowired
	private BatchUserRepository batchUserRepository;
	
	@Autowired
	private BatchCcRepository batchCcRepository;
	
	public static class CheckQualityBatchEntityVo extends EntityVo<CheckQualityBatch, String> {
		public CheckQualityBatchEntityVo(CheckQualityBatch entity) {
			super(entity);
		}
		@JsonProperty("batchType")
		public BatchType getBatchType() {
			return entity.getBatchType();
		}
		@JsonProperty("bidSectionId")
		public String getBidSectionId() {
			return entity.getBidSectionId();
		}
		@JsonProperty("name")
		public String getName() {
			return entity.getName();
		}
		@JsonProperty("repairDeadline")
		public int getRepairDeadline() {
			return entity.getRepairDeadline();
		}
		@JsonProperty("isClose")
		public Byte getIsClose() {
			return entity.getIsClose();
		}
		@JsonProperty("batchPurpose")
		public BatchPurpose getBatchPurpose() {
			return entity.getBatchPurpose();
		}
		@JsonProperty("inChargeBy")
		public String inChargeBy() {
			return entity.getInChargeById();
		}
	}

	@Getter
	@Setter
	public static class CheckQualityBatchFormVo extends FormVo<String> {
		@Size(min = 1, message = "批次名称不能为空")
		private String name;
		private String batchType;
		private String bidSectionId;
		private int repairDeadline;
		private List<String> registIds = new LinkedList<String>();
		private String chargeId;
		private List<String> ccIds = new LinkedList<String>();
	}
	
	@Override
	public IRepository<CheckQualityBatch, String> getRepository() {
		return repository;
	}
	
	@RequestMapping("close")
	@Transactional 
	public RestResponseElement close( @CurrentUser User user,
				@RequestParam("batchId") String batchId ){
		CheckQualityBatch checkQualityBatch = this.getRepository().findById(batchId).orElse(null);
		checkQualityBatch.setIsClose((byte)1);
		this.getRepository().saveAndFlush(checkQualityBatch);
		RestResponseElement response = new RestResponseElement();
		response.setSuccess(true);
		response.setElement(this.generateEntityVo(checkQualityBatch));
		return response;
	}

	@Override
	@Transactional
	public void processEditEntity(CheckQualityBatchFormVo form, CheckQualityBatch entity) {
		entity.setName(form.getName());
		entity.setRepairDeadline(form.getRepairDeadline());
		entity.setInChargeBy(userRepository.findById(form.getChargeId()).orElse(null));
		this.getRepository().saveAndFlush(entity);
		List<BatchUser> batchUserList = batchUserRepository.findByCheckQualityBatch(entity);
		batchUserRepository.deleteAll(batchUserList);
		form.getRegistIds().forEach(registId -> {
			BatchUser batchUser = new BatchUser();
			batchUser.setCheckQualityBatch(entity);
			batchUser.setUser(userRepository.findById(registId).orElse(null));
			batchUserRepository.saveAndFlush(batchUser);
		});
		List<BatchCc> batchCcList = batchCcRepository.findByCheckQualityBatch(entity);
		batchCcRepository.deleteAll(batchCcList);
		form.getCcIds().forEach(ccId -> {
			BatchCc batchCc = new BatchCc();
			batchCc.setCheckQualityBatch(entity);
			batchCc.setUser(userRepository.findById(ccId).orElse(null));
			batchCcRepository.saveAndFlush(batchCc);
		});
	}

	@Override
	@Transactional
	public void processAddEntity(CheckQualityBatchFormVo form, CheckQualityBatch entity) {
		entity.setBatchPurpose(BatchPurpose.正式);
		entity.setBatchType(BatchType.convert(form.getBatchType()));
		entity.setName(form.getName());
		entity.setBidSection(bidSectionRepository.findById(form.getBidSectionId()).orElse(null));
		entity.setRepairDeadline(form.getRepairDeadline());
		entity.setInChargeBy(userRepository.findById(form.getChargeId()).orElse(null));
		entity.setIsClose((byte)0);
		this.getRepository().saveAndFlush(entity);
		form.getRegistIds().forEach(registId -> {
			BatchUser batchUser = new BatchUser();
			batchUser.setCheckQualityBatch(entity);
			batchUser.setUser(userRepository.findById(registId).orElse(null));
			batchUserRepository.saveAndFlush(batchUser);
		});
		form.getCcIds().forEach(ccId -> {
			BatchCc batchCc = new BatchCc();
			batchCc.setCheckQualityBatch(entity);
			batchCc.setUser(userRepository.findById(ccId).orElse(null));
			batchCcRepository.saveAndFlush(batchCc);
		});
	}
}
